using System;
using System.Diagnostics;

namespace Magiq.Behaviors
{
    public abstract class MagiqBehavior : IMagiqBehavior
    {
        private IMagiqBehavior nextBehavior;

        #region IMagiqBehavior Members

        public IMagiqBehavior NextBehavior
        {
            get { return nextBehavior; }
            set
            {
                if (value != null)
                    value.NextBehavior = nextBehavior;

                nextBehavior = value;
            }
        }

        #endregion

        [DebuggerStepThrough]
        public static TReturn Execute<TBehavior, TReturn>(IMagiqBehavior behavior, Func<TBehavior, TReturn> action)
        {
            if (behavior == null)
                return default(TReturn);

            if (!(behavior is TBehavior))
                return Execute(behavior.NextBehavior, action);

            return action((TBehavior) behavior);
        }

        [DebuggerStepThrough]
        public static void Execute<TBehavior>(IMagiqBehavior behavior, Action<TBehavior> action)
        {
            if (behavior == null)
                return;

            if (!(behavior is TBehavior))
            {
                Execute(behavior.NextBehavior, action);
                return;
            }

            action((TBehavior) behavior);
        }

        [DebuggerStepThrough]
        protected IMagiqBehaviorCaller<TBehavior> Next<TBehavior>() where TBehavior : IMagiqBehavior
        {
            return new MagiqBehaviorCaller<TBehavior>(NextBehavior);
        }
    }
}